using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
/// <summary>
/// 加密解密扩展
/// </summary>
public static class HFCryptionExtend
{


    #region MD5加密
    /// <summary>
    /// md5转换器
    /// </summary>
    readonly static MD5 mMD5CryptoServiceProvider = new MD5CryptoServiceProvider();
    /// <summary>
    /// MD5加密
    /// </summary>
    /// <param name="_str">要加密的字符</param>
    /// <returns>加密后的字符</returns>
    public static string HFMD5(this string _str)
    {
        return BitConverter.ToString(_str.HFMD5Hash());
    }

    /// <summary>
    /// MD5加密
    /// </summary>
    /// <param name="_buffer">buffer</param>
    /// <returns>加密后的字符</returns>
    public static string HFMD5(this byte[] _buffer)
    {
        return BitConverter.ToString(_buffer);
    }    

    /// <summary>
    /// MD5Hash流
    /// </summary>
    /// <param name="_str">字符串</param>
    /// <returns>MD5Hash流</returns>
    public static byte[] HFMD5Hash(this string _str)
    {
        return mMD5CryptoServiceProvider.ComputeHash(Encoding.UTF8.GetBytes(_str));
    }

    /// <summary>
    /// MD5Hash流
    /// </summary>
    /// <param name="_inputStream">输入流</param>
    /// <returns>MD5Hash流</returns>
    public static byte[] HFMD5Hash(Stream _inputStream)
    {
        return mMD5CryptoServiceProvider.ComputeHash(_inputStream);
    }

    /// <summary>
    /// MD5Hash流
    /// </summary>
    /// <param name="_buffer">buffer</param>
    /// <param name="_offset">offset</param>
    /// <param name="_count">count</param>
    /// <returns>MD5Hash流</returns>
    public static byte[] HFMD5Hash(byte[] _buffer, int _offset, int _count)
    {
        return mMD5CryptoServiceProvider.ComputeHash(_buffer, _offset, _count);
    }

    /// <summary>
    /// MD5Hash流
    /// </summary>
    /// <param name="_buffer">buffer</param>
    /// <returns>MD5Hash流</returns>
    public static byte[] HFMD5Hash(byte[] _buffer)
    {
        return mMD5CryptoServiceProvider.ComputeHash(_buffer);
    }
    #endregion

    #region AES加密

    /// <summary>
    /// AES加密
    /// </summary>
    /// <param name="Key">key 例如：【WgsergmzsjdfgOEWRGNJRNGmkzaksme】  </param>
    /// <returns>密文</returns>
    public static string AESEncrypt(this string encryptStr, string Key)
    {
        byte[] keyArray = System.Text.UTF8Encoding.UTF8.GetBytes(Key);
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(encryptStr);
        RijndaelManaged rDel = new RijndaelManaged();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateEncryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }
    /// <summary>
    /// AES解密
    /// </summary>
    /// <param name="Key">key 例如：【WgsergmzsjdfgOEWRGNJRNGmkzaksme】  </param>
    /// <returns>解密后文件</returns>
    public static string AESDEncrypt(this string encryptStr, string Key)
    {
        byte[] keyArray = UTF8Encoding.UTF8.GetBytes(Key);
        byte[] toEncryptArray = Convert.FromBase64String(encryptStr);
        RijndaelManaged rDel = new RijndaelManaged();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateDecryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        return UTF8Encoding.UTF8.GetString(resultArray);
    }

    /// <summary>
    /// 将字符串解码到固定长度的数组中
    /// </summary>
    static byte[] StringEncodeFixedLengthArray(string content, int length)
    {
        byte[] data = Encoding.ASCII.GetBytes(content);
        Array.Resize(ref data, length);
        return data;
    }
    /// <summary>
    /// Aes加密
    /// </summary>
    /// <param name="data">需要加密的内容</param>
    /// <param name="aeskey">key 例如：【WgsergmzsjdfgOEWRGNJRNGmkzaksme】  </param>
    /// <param name="aesiv">aesiv 例如：【SOJGGpjrepgjaskgpojAJGoe;lrmg】 </param>
    public static byte[] AesEncrypt(this byte[] data,string aeskey,string aesiv)
    {
        byte[] result;
        using (Aes aes = Aes.Create())
        {
            aes.Key = StringEncodeFixedLengthArray(aeskey, 32);//32不要乱改，改成其他值可能会出错
            aes.IV = StringEncodeFixedLengthArray(aesiv, 16);//16不要乱改，改成其他值可能会出错

            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
            result = encryptor.TransformFinalBlock(data, 0, data.Length);
            encryptor.Dispose();
        }

        return result;
    }

    /// <summary>
    /// Aes解密
    /// </summary>
    /// <param name="data">需要解密的内容</param>
    /// <param name="aeskey">key 例如：【WgsergmzsjdfgOEWRGNJRNGmkzaksme】  </param>
    /// <param name="aesiv">aesiv 例如：【SOJGGpjrepgjaskgpojAJGoe;lrmg】 </param>
    /// <returns></returns>
    public static byte[] AesDecrypt(this byte[] data, string aeskey, string aesiv)
    {
        byte[] result;
        using (Aes aes = Aes.Create())
        {
            aes.Key = StringEncodeFixedLengthArray(aeskey, 32);//32不要乱改，改成其他值可能会出错
            aes.IV = StringEncodeFixedLengthArray(aesiv, 16);//16不要乱改，改成其他值可能会出错

            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
            result = decryptor.TransformFinalBlock(data, 0, data.Length);
            decryptor.Dispose();
        }
        return result;
    }
    #endregion
}
